﻿Imports Microsoft.Win32
Imports System.Management
Imports System.Threading

Public Class frm_Main
    Private Const RegPath As String = "SOFTWARE\DG\BLPin"
    Private Const RegKeyForce As String = "force"
    Private MyRegKey As RegistryKey = Nothing
    Private forceEnabled As Boolean = Nothing
    Private parameterList As String = Command()

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Try
            MyRegKey = Registry.LocalMachine.OpenSubKey(RegPath, True)
            forceEnabled = CType(MyRegKey.GetValue(RegKeyForce, False), Boolean)
        Catch ex As Exception
            forceEnabled = False
        End Try

        If parameterList.Equals("-autorun") AndAlso Not forceEnabled Then
            Application.Exit()
        End If

        Me.WindowState = FormWindowState.Normal
        Button2.Enabled = Not forceEnabled
    End Sub

    Private Sub Form1_FormClosing(ByVal sender As System.Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles MyBase.FormClosing
        If forceEnabled Then
            'MsgBox("Bitte erst eine PIN setzen", MsgBoxStyle.Information)
            MsgBox("You have to set the PIN first.", MsgBoxStyle.Information)
            e.Cancel = True
        ElseIf Not forceEnabled Then
            e.Cancel = False
        ElseIf TextBox1.Text.Equals("") OrElse TextBox2.Text.Equals("") Then
            'MsgBox("Bitte erst eine PIN setzen", MsgBoxStyle.Information)
            MsgBox("You have to set the PIN first.", MsgBoxStyle.Information)
            e.Cancel = True
        Else
            e.Cancel = False
        End If
    End Sub

    'Damit das Fenster nicht verschoben werden kann
    Protected Overloads Overrides Sub WndProc(ByRef m As Message)
        Select Case m.Msg
            Case WM_SYSCOMMAND
                Dim cmd As Int32 = m.WParam.ToInt32 And &HFFF0
                If cmd = SC_MOVE Then
                    Return
                End If
        End Select
        MyBase.WndProc(m)
    End Sub

    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        Application.Exit()
    End Sub

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        If Not TextBox2.Text.Equals(TextBox1.Text) OrElse TextBox1.Text.Equals("") Then
            'MsgBox("Die Passwörter sind nicht gleich, bzw. es wurde kein Passwort eingegeben")
            MsgBox("The given PINs are not equal or empty")
            TextBox1.Focus()
            TextBox1.SelectAll()
        Else
            Dim mScope As ManagementScope = New ManagementScope("ROOT\CIMV2\Security\MicrosoftVolumeEncryption")
            'Dim mPath As ManagementPath = New ManagementPath("CIMV2\Security\MicrosoftVolumeEncryption")
            'Dim mClass As ManagementClass = New ManagementClass(mScope, mPath, Nothing)

            Dim mSearchString As String = "Select * from Win32_EncryptableVolume"
            Dim mQuery = New WqlObjectQuery(mSearchString)

            Dim mSearch = New ManagementObjectSearcher(mScope, mQuery, Nothing)

            For Each mObject As ManagementObject In mSearch.Get
                ' MsgBox(mObject("DeviceID").ToString)
                If mObject.Properties("DriveLetter").Value.ToString.ToLower.Equals("c:") Then
                    Dim params As ManagementBaseObject = mObject.GetMethodParameters("ProtectKeyWithTPMAndPIN")
                    params.Properties("PIN").Value = TextBox1.Text
                    Dim result As ManagementBaseObject = mObject.InvokeMethod("ProtectKeyWithTPMAndPIN", params, Nothing)
                    If result.Properties("returnvalue").Value.ToString.Equals("2150694961") Then
                        params = mObject.GetMethodParameters("GetKeyProtectors")
                        params.Properties("KeyProtectorType").Value = 4
                        Dim volumeKeyProtectorID As String = mObject.InvokeMethod("GetKeyProtectors", params, Nothing).Properties("VolumeKeyProtectorID").Value(0)

                        params = mObject.GetMethodParameters("ChangePIN")
                        params.Properties("NewPIN").Value = TextBox1.Text

                        params.Properties("VolumeKeyProtectorID").Value = volumeKeyProtectorID
                        result = mObject.InvokeMethod("ChangePIN", params, Nothing)

                        Dim resultInt As Long = Nothing
                        Try
                            resultInt = Long.Parse(result.Properties("returnvalue").Value)
                        Catch ex As Exception
                            resultInt = -1
                        End Try

                        If checkForError(resultInt) Then
                            Application.Exit()
                        Else
                            TextBox1.Focus()
                            TextBox1.SelectAll()
                        End If
                    Else
                        If checkForError(Long.Parse(result.Properties("returnvalue").Value)) Then
                            Application.Exit()
                        Else
                            TextBox1.Focus()
                            TextBox1.SelectAll()
                        End If
                    End If
                End If
            Next
        End If
    End Sub

    Private Function checkForError(ByVal errorNumber As Long) As Boolean
        Select Case errorNumber
            Case 0
                forceEnabled = False
                Try
                    MyRegKey.SetValue(RegKeyForce, 0, RegistryValueKind.DWord)
                    'MsgBox("PIN wurde gesetzt", MsgBoxStyle.Information)
                    MsgBox("PIN was set successfull", MsgBoxStyle.Information)
                    Return True
                Catch ex As Exception
                    Try
                        Dim buildKey As RegistryKey = Registry.LocalMachine.OpenSubKey("SOFTWARE", True)
                        buildKey.CreateSubKey("DG")
                        buildKey.Close()
                        buildKey = Registry.LocalMachine.OpenSubKey("SOFTWARE\DG", True)
                        buildKey.CreateSubKey("BLPin")
                        buildKey.Close()
                        buildKey = Registry.LocalMachine.OpenSubKey("SOFTWARE\DG\BLPin")
                        buildKey.SetValue(RegKeyForce, 0, RegistryValueKind.DWord)
                        buildKey.Close()
                        'MsgBox("PIN wurde gesetzt", MsgBoxStyle.Information)
                        MsgBox("PIN was set successfull", MsgBoxStyle.Information)
                        Return True
                    Catch ex2 As Exception
                        'MsgBox("Konnte RegKey nicht schreiben", MsgBoxStyle.Exclamation)
                        MsgBox("Could not write RegKey", MsgBoxStyle.Exclamation)
                    End Try
                End Try
            Case 2150694960
                MsgBox("A bootable CD/DVD is found in this computer. Remove the CD/DVD and restart the computer.", MsgBoxStyle.Exclamation)
            Case 2150695066
                MsgBox("The NewPIN parameter contains characters that are not valid. When the ""Allow enhanced PINs for startup"" Group Policy is disabled, only numbers are supported.", MsgBoxStyle.Exclamation)
            Case 2150694970
                MsgBox("The VolumeKeyProtectorID parameter does not refer to a key protector of the type ""Numerical Password"" or ""External Key"". Use either the ProtectKeyWithNumericalPassword or ProtectKeyWithExternalKey method to create a key protector of the appropriate type.", MsgBoxStyle.Exclamation)
            Case 2150694912
                MsgBox("The volume is locked.", MsgBoxStyle.Exclamation)
            Case 2150694920
                MsgBox("BitLocker is not enabled on the volume. Add a key protector to enable BitLocker.", MsgBoxStyle.Exclamation)
            Case 2150695016
                MsgBox("The NewPIN parameter supplied is either longer than 20 characters, shorter than 4 characters, or shorter than the minimum length specified by Group Policy.", MsgBoxStyle.Exclamation)
            Case 2150694963
                MsgBox("The provided key protector does not exist on the volume.", MsgBoxStyle.Exclamation)
            Case 2150121480
                MsgBox("No compatible Trusted Platform Module (TPM) is found on this computer.", MsgBoxStyle.Exclamation)
            Case 2150694961
                MsgBox("A key protector of this type already exists.", MsgBoxStyle.Exclamation)
            Case 2150694947
                MsgBox("The TPM cannot secure the volume's encryption key because the volume does not contain the currently running operating system.", MsgBoxStyle.Exclamation)
            Case 2150695066
                MsgBox("The NewPIN parameter contains characters that are not valid. When the ""Allow enhanced PINs for startup"" Group Policy is disabled, only numbers are supported.", MsgBoxStyle.Exclamation)
            Case 2150121480
                MsgBox("No compatible TPM is found on this computer", MsgBoxStyle.Exclamation)
            Case Else
                MsgBox("Error while setting the PIN. Please contact your helpdesk.", MsgBoxStyle.Exclamation)
        End Select
        Return False
    End Function

    Private Sub TextBox1_Enter(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox1.Enter
        TextBox1.SelectAll()
    End Sub

    Private Sub TextBox2_Enter(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox2.Enter
        TextBox2.SelectAll()
    End Sub

    Private Sub TextBox2_KeyPress(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles TextBox2.KeyPress
        Select Case Asc(e.KeyChar)
            Case 13
                Button1.Enabled = False
                Button1_Click(Me, Nothing)
                Button1.Enabled = True
        End Select
    End Sub

    Private Sub TextBox1_KeyPress(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles TextBox1.KeyPress
        Select Case Asc(e.KeyChar)
            Case 13
                TextBox2.Focus()
        End Select
    End Sub

    Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
        Dim mScope As ManagementScope = New ManagementScope("ROOT\CIMV2\Security\MicrosoftVolumeEncryption")
        'Dim mPath As ManagementPath = New ManagementPath("CIMV2\Security\MicrosoftVolumeEncryption")
        'Dim mClass As ManagementClass = New ManagementClass(mScope, mPath, Nothing)

        Dim mSearchString As String = "Select * from Win32_EncryptableVolume"
        Dim mQuery = New WqlObjectQuery(mSearchString)

        Dim mSearch = New ManagementObjectSearcher(mScope, mQuery, Nothing)

        For Each mObject As ManagementObject In mSearch.Get
            If mObject.Properties("DriveLetter").Value.ToString.ToLower.Equals("c:") Then
                'mObject.InvokeMethod("PauseConversion", Nothing)
                mObject.InvokeMethod("DisableKeyProtectors", Nothing)
                ProgressBar1.Visible = True
                ProgressBar1.Minimum = 0
                ProgressBar1.Maximum = 11
                ProgressBar1.Step = 1
                For i As Integer = 0 To 10
                    ProgressBar1.Value += 1
                    Thread.Sleep(1000)
                Next
                ProgressBar1.Visible = False
                'mObject.InvokeMethod("ResumeConversion", Nothing)
                mObject.InvokeMethod("EnableKeyProtectors", Nothing)
                'If outParams("returnValue").ToString() = "0" Then
                'MsgBox(outParams("returnValue").ToString())
                'End If

            End If
        Next
    End Sub
End Class

Public Module Win32Api
    Public Const SC_MOVE As Int32 = &HF010
    Public Const WM_SYSCOMMAND As Int32 = &H112
End Module